<?php if ( ! defined('BASEPATH')) exit('This file does not run directly. Sorry.'); ?>
<?php
/**
 * Kalaisoo.
 *
 * A lightweight no-framework framework written in PHP.
 *
 * @package Kalaisoo
 * @author $Author: info@sah-company.com $
 * @version $Id: cms.php 126 2012-01-11 20:59:15Z info@sah-company.com $
 */

/**
 * Kalaisoo Cms Plugin Class.
 *
 * @package Kalaisoo
 * @subpackage Plugin
 * @author $Author: info@sah-company.com $
 */
class Cms_Plugin extends Plugin
{
	/**
	 * The current path. This is the url without the language code.
	 *
	 * @var string $path
	 */
	protected $path;

	/**
	 * The found page, if any.
	 *
	 * @var Bean
	 */
	protected $page;

	/**
	 * constructs a new Cms_Plugin and initializes it.
	 */
	public function __construct()
	{
		parent::__construct();
		$this->init();
	}
	
	/**
	 * starts a session, loads redbean, some helpers, the language file and Model_Page.
	 */
	protected function init()
	{
		session_start();
		$this->registry->loader->lib(array('redbean'));
		$this->registry->loader->helper(array('url', 'textile')); // textile we need anyway
		$this->registry->loader->language('cms');
		$this->registry->loader->model(array('page'));
	}
	
	/**
	 * looksup the url in page beans and output a webpage or 404.
	 *
	 * @todo refactor code
	 */
	public function execute()
	{
		$this->registry->logger->log('... Plugin cms has taken over, due to unfound controller');
		$curl = explode('/', $this->registry->router->url()); // split url into
		$languageCode = array_shift($curl);
		$this->path = implode('/', $curl);
		$this->page = R::findOne('page', ' url = :path', array(':path' => $this->path));
		if ( ! $this->page || ! $this->page->getId()) {
			return $this->controller()->error('404 - path not found');
		}
		$page_localized = $this->findLocalizedPage($languageCode);
		if ($page_localized === false) {
			return $this->controller()->return('404 - requested language not found');
		}
		if ( ! $this->auth()) return false;
		if ( ! $this->page->cacheable) $this->registry->cache->setLifetime(0);
		// build areas
		$areas = array();
		$areas['lng_code'] = $languageCode;
		$areas['base_href'] = BASEURL.'/';
		$areas['title'] = htmlspecialchars($page_localized->name);
		$areas['meta_author'] = '';
		$areas['meta_keywords'] = htmlspecialchars($page_localized->meta_keywords);
		$areas['meta_description'] = htmlspecialchars($page_localized->meta_description);
		foreach ($page_localized->ownPage_area as $n=>$area) {
			foreach ($area->ownPage_slice as $m=>$slice) {
				$areas[$area->name][] = $this->makeContent($slice); 
			}
		}		
		$this->registry->logger->log('Plugin cms displays page');
		echo $this->mixTemplateWithContent($this->page->template, $areas);
	}
	
	/**
	 * returns the result of mixing the template with content.
	 *
	 * @param Bean $template
	 * @param array $areas
	 * @return string
	 */
	protected function mixTemplateWithContent($template, $areas)
	{
		$mixedResult = $template->content;
		foreach ($areas as $partName=>$content) {
			$needle = '{'.strtolower($partName).'}';
			$haystack = (is_array($content)) ? implode("\n", $content) : $content;
			$mixedResult = str_replace($needle, $haystack, $mixedResult);
		}
		return $mixedResult;
	}
	
	/**
	 * returns the content of slice.
	 *
	 * This generates the content, which is build by the module of slice and using slices
	 * raw content.
	 *
	 * @see sys/helpers/* Any of those could be a module for content.
	 *
	 * @param mixed $slice
	 * @return string
	 */
	protected function makeContent($slice)
	{
		// push slice into area
		$module = strtolower($slice->module);
		if ($module == 'text') return htmlspecialchars($slice->content);
		if ($module == 'html') return $slice->content;
		$this->registry->loader->helper($module);
		return $module($slice->content);
	}
	
	
	/**
	 * returns a Model_PageLocalized or false.
	 *
	 * @param string $languageCode
	 * @return mixed
	 */
	protected function findLocalizedPage($languageCode)
	{
		foreach ($this->page->ownPage_localized as $id=>$localized) {
			if ($localized->language == $languageCode) return $localized;
		}
		return false;
	}
	
	/**
	 * returns true if user session can see the page or false if not.
	 *
	 * If the page is password protected and user is not yet authorized
	 * a password dialog is presented. Otherwise (bool)true is returned.
	 *
	 * @return bool
	 */
	protected function auth()
	{
		if (empty($this->page->pw)) return true;
		if ($this->page->pw == 'da39a3ee5e6b4b0d3255bfef95601890afd80709') return true;
		$this->registry->logger->log('Plugin cms found a password protected page');
		$this->registry->cache->setLifetime(0);
		if (isset($_SESSION['page_auth'][$this->page->getId()])) return true;
		$input = new Input();
		if ($input->submit) {
			if (sha1($input->pw) == $this->page->pw) {
				$_SESSION['page_auth'][$this->page->getId()] = true;
				return $this->controller()->redirect(ahref($this->registry->router->url()));
			} else {
				$this->controller()->data['errors']['fn_pw'] = __('cms_pw_invalid');
			}
		}
		// client is not authorized yet, spit out a password dialog
		$this->registry->logger->log('Plugin cms displays the password dialog');
		$template = new Template();
		$this->controller()->data['pageTitle'] = __('cms_password_title');
		$this->controller()->data['url'] = $this->registry->router->url();
		$template->view('shared/cms/password', $this->controller()->data);
		return false;
	}
	
	/**
	 * returns true if there is a user session or false if not.
	 *
	 * @return bool
	 */
	public function checkForActiveUser()
	{
		if ( ! $this->controller()->user() || ! $this->controller()->user()->isAuth()) return false;
		$this->registry->logger->log('Plugin cms found a active user session');
		$this->data['scripts'][] = 'cms';
		return true;
	}
}